import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ModbusCRC16Calculator extends JFrame {
    private JTextField inputField;
    private JButton calculateButton;
    private JButton clearButton;
    private JLabel resultLabel;

    public ModbusCRC16Calculator() {
        setTitle("Modbus CRC-16计算器");
        setSize(400, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        setLocationRelativeTo(null);

        inputField = new JTextField(20);
        calculateButton = new JButton("计算CRC-16");
        clearButton = new JButton("清除"); // 初始化清除按钮
        resultLabel = new JLabel("结果：");

        // 添加按钮点击事件监听器
        calculateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String hexInput = inputField.getText();
                try {
                    int crc16 = calculateCRC16(hexInput);
                    crc16 = ((crc16 & 0x00FF) << 8) | ((crc16 & 0xFF00) >> 8);
                    resultLabel.setText("结果：" + String.format("%04X", crc16));
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(null, "输入的数据格式不正确，请输入有效的十六进制数据。");
                }
            }
        });

        // 添加清除按钮点击事件监听器
        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                inputField.setText(""); // 清空输入框
                resultLabel.setText("结果："); // 清空结果显示
            }
        });

        // 创建面板并设置布局
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());
        panel.add(new JLabel("输入Modbus数据（十六进制）："));
        panel.add(inputField);
        panel.add(calculateButton);
        panel.add(clearButton); // 添加清除按钮到面板
        panel.add(resultLabel);

        // 将面板添加到窗口
        add(panel);

        // 创建菜单栏
        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);

        // 创建文件菜单
        JMenu fileMenu = new JMenu("文件");
        menuBar.add(fileMenu);

        // 创建编辑菜单
        JMenu editMenu = new JMenu("编辑");
        menuBar.add(editMenu);

        // 创建帮助菜单
        JMenu helpMenu = new JMenu("帮助");
        menuBar.add(helpMenu);

        // 创建菜单项
        JMenuItem saveItem = new JMenuItem("保存");
        JMenuItem loadItem = new JMenuItem("加载");
        JMenuItem quitItem = new JMenuItem("退出");

        // 添加菜单项到文件菜单
        fileMenu.add(saveItem);
        fileMenu.add(loadItem);
        fileMenu.addSeparator(); // 添加分隔线
        fileMenu.add(quitItem);

        // 添加动作监听器到菜单项
        quitItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        // 您可以为saveItem和loadItem添加相应的动作监听器
    }

    // 计算CRC-16的函数
    private int calculateCRC16(String hexInput) throws NumberFormatException {
        // 将十六进制字符串转换为字节数组
        int len = hexInput.length();
        if (len % 2 != 0) {
            throw new NumberFormatException("输入的十六进制字符串长度必须为偶数。");
        }
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexInput.charAt(i), 16) << 4)
                                 + Character.digit(hexInput.charAt(i + 1), 16));
        }

        // CRC-16计算过程
        int crc = 0xFFFF;
        for (byte b : data) {
            crc ^= (b & 0xFF);
            for (int i = 0; i < 8; i++) {
                if ((crc & 0x0001) != 0) {
                    crc >>= 1;
                    crc ^= 0xA001;
                } else {
                    crc >>= 1;
                }
            }
        }
        return crc;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                ModbusCRC16Calculator calculator = new ModbusCRC16Calculator();
                calculator.setVisible(true);
            }
        });
    }
}
